#pragma once

#include <iostream>
#include <memory>
#include <sstream>
#include <sys/types.h>
#include <unistd.h>
#include <filesystem>
#include <fstream>
#include <sys/wait.h>

static std::string newfilename;

class HandlerText
{

public:
    HandlerText() : _enable(true)
    {
    }

    virtual ~HandlerText() = default;

    virtual void Execute(std::string &text)
    {
    }
    bool IsEnable()
    {
        return _enable;
    }

    void Enble()
    {
        _enable = true;
    }

    void DisEnble()
    {
        _enable = false;
    }

    void SetNextHandler(std::shared_ptr<HandlerText> handler)
    {
        _next_handler = handler;
    }

protected:
    std::shared_ptr<HandlerText> _next_handler;
    bool _enable;
};

// 格式化处理
class HandlerTextFormat : public HandlerText
{

public:
    void Execute(std::string &text) override
    {
        if (HandlerText::IsEnable())
        {
            std::cout << "1.开始格式化处理 Format…… " << std::endl;
            std::stringstream ss;
            ss << time(nullptr) << "-" << getpid() << "-" << text << "\n";
            text = ss.str();
        }
        if (_next_handler)
        {
            _next_handler->Execute(text);
        }
        else
        {
            std::cout << "责任链节点结束，处理完成！" << std::endl;
        }
    }
};

std::string defaultpath = "./tmp/";
std::string defaultfilename = "test.log";

// 保存至文件当中
class HandlerTextSaveFile : public HandlerText
{

public:
    HandlerTextSaveFile() : _filepath(defaultpath), _filename(defaultfilename)
    {
        if (std::filesystem::exists(_filename))
        {
            return;
        }

        try
        {
            std::filesystem::create_directories(_filepath);
        }
        catch (std::filesystem::filesystem_error &e)
        {
            std::cerr << e.what() << std::endl;
        }
    }
    ~HandlerTextSaveFile()
    {
    }

    void Execute(std::string &text) override
    {
        if (HandlerText::IsEnable())
        {
            std::cout << "2.保存至指定" << _filename << "文件当中,Save……" << std::endl;
            std::string file = _filepath + _filename;
            std::ofstream out(file, std::ios::app);
            if (!out.is_open())
                return;
            out << text;
            out.close();
        }
        if (_next_handler)
        {
            _next_handler->Execute(text);
        }
        else
        {
            std::cout << "责任链节点结束，处理完成！" << std::endl;
        }
    }

private:
    std::string _filepath;
    std::string _filename;
};

const int maxline = 5;

// 备份文件
class HandlerTextBackupFile : public HandlerText
{
public:
    HandlerTextBackupFile()
        : _max_line_number(maxline), _filename(defaultfilename), _filepath(defaultpath)
    {
    }
    ~HandlerTextBackupFile()
    {
    }

    void BackUp()
    {
        std::string newname = _filename + "." + std::to_string(time(nullptr));
        pid_t pid = fork();
        if (pid == 0)
        {
            // 子进程
            chdir(_filepath.c_str());
            std::filesystem::rename(_filename, newname);
            std::string tarname = newname + ".tgz";
            std::cout << "4.打包：" << newname << "成为：" << tarname << std::endl;
            execlp("tar", "tar", "-czf", tarname.c_str(), newname.c_str(), nullptr);
            exit(1);
        }

        int status = 0;
        pid_t wat = waitpid(pid, &status, 0);
        (void)wat;
        if (wat > 0 && WIFEXITED(status))
        {
            std::string tmpfile = _filepath + newname;
            std::filesystem::remove(tmpfile);
        }
    }

    void Execute(std::string &text) override
    {
        if (HandlerText::IsEnable())
        {
            std::cout << "3.进行文件备份,Backup……" << std::endl;
            const std::string filename = _filepath + _filename;
            std::ifstream in(filename, std::ios::in);
            if (!in.is_open())
                return;
            std::string line;
            int countline = 0;
            while (std::getline(in, line))
            {
                countline++;
            }
            in.close();

            if (countline > _max_line_number)
            {
                std::cout << "消息行超过" << _max_line_number << "行，触发文件备份" << std::endl;
                BackUp();
            }
        }

        if (_next_handler)
        {
            _next_handler->Execute(text);
        }
        else
        {
            std::cout << "责任链节点结束，处理完成！" << std::endl;
        }
    }

private:
    int _max_line_number;
    std::string _filepath;
    std::string _filename;
};


class HandlerEntry
{

public:
    HandlerEntry()
    {

        _format = std::make_shared<HandlerTextFormat>();
        _save = std::make_shared<HandlerTextSaveFile>();
        _backup = std::make_shared<HandlerTextBackupFile>();

        _format->SetNextHandler(_save);
        _save->SetNextHandler(_backup);
    }

    void Run(std::string &text)
    {
        _format->Execute(text);
    }

    void EnableHandler(bool isformat, bool issave, bool isbackup)
    {
        isformat ? _format->Enble() : _format->DisEnble();
        issave ? _save->Enble() : _save->DisEnble();
        isbackup ? _backup->Enble() : _backup->DisEnble();
    }

private:
    std::shared_ptr<HandlerText> _format;
    std::shared_ptr<HandlerText> _save;
    std::shared_ptr<HandlerText> _backup;
};